//
//  ColorPannicView.swift
//  书笺
//
//  Created by 张旭晟 on 2023/12/29.
//

import SwiftUI
import Glazed

struct IdentifiableColor: Codable, Equatable, Identifiable {
    var id: UUID = UUID()
    var color: CodableColor
}

@MainActor var colors: [IdentifiableColor] = {
    do {
        @AppStorage("ColorPannicCodeable") var ColorPannicCodeable:Data = Data()
        return try PropertyListDecoder().decode([IdentifiableColor].self, from: ColorPannicCodeable)
    } catch {
        return [.black, .gray, .tintColor, .purple, .blue, .systemMint, .systemTeal, .systemCyan, UIColor(red: 0.475, green: 0.831, blue: 0.459, alpha: 1), UIColor(red: 0.5921, green: 0.9607, blue: 0.53333, alpha: 1), .systemYellow, .yellow, .red, .systemRed, .systemPink, .systemIndigo].map({ UIcolor in
            IdentifiableColor(color: CodableColor(UIcolor))
        })
    }
}() {
    didSet {
        @AppStorage("ColorPannicCodeable") var ColorPannicCodeable:Data = Data()
        
        do {
            ColorPannicCodeable = try PropertyListEncoder().encode(colors)
        } catch {}
    }
}
public struct ColorPannicView: View {
    @Binding var DefColor:UIColor
    var mustOnColor:[UIColor] = []
    
    @State private var showColorPicker = false
    @State private var AddColor: UIColor = .clear
    @State private var Colors: [IdentifiableColor] = colors {
        didSet {
            colors = Colors
        }
    }
    
    public init(DefColor: Binding<UIColor>, mustOnColor: [UIColor] = []) {
        self._DefColor = DefColor
        self.mustOnColor = mustOnColor
    }
    
    public var body: some View {
        VStack(spacing: 8) {
            ScrollView {
                pickers()
            }
            .frame(maxWidth: .infinity)
            opSet()
                .padding([.leading, .trailing, .bottom], 12)
        }
        .frame(maxWidth: 370, maxHeight: 320)
        .animation(.autoAnimation, value: DefColor)
    }
    
    @ViewBuilder
    func pickers() -> some View {
        LazyVGrid(columns: [GridItem(.adaptive(minimum: 40, maximum: 40), spacing: 12)], spacing: 12) {
            if !mustOnColor.isEmpty {
                Section {
                    ForEach(mustOnColor, id: \.self) { color in
                        Button {
                            DefColor = color
                        } label: {
                            Color(color)
                                .frame(width: 40, height: 40)
                                .background(.white)
                                .overlay {
                                    if DefColor == color {
                                        RoundedRectangle(cornerRadius: 8, style: .continuous)
                                            .stroke(lineWidth: 8)
                                            .foregroundStyle(.white)
                                    }
                                }
                                .clipShape(RoundedRectangle(cornerRadius: 8))
                        }
                    }
                } header: {
                    Text("推荐")
                       .font(.custom(size: .footnote))
                        .foregroundStyle(.gray)
                        .padding(.horizontal, 4)
                        .frame(height: 50)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
            
            Section {
                ForEach(Colors) { color in
                    Button {
                        DefColor = color.color.UIColor
                    } label: {
                        Color(color.color.UIColor)
                            .frame(width: 40, height: 40)
                            .background(.white)
                            .overlay {
                                if DefColor == color.color.UIColor {
                                    RoundedRectangle(cornerRadius: 8, style: .continuous)
                                        .stroke(lineWidth: 8)
                                        .foregroundStyle(.white)
                                }
                            }
                            .clipShape(RoundedRectangle(cornerRadius: 8))
                    }
                    .contextMenu {
                        Button(role: .destructive) {
                            if let int = Colors.firstIndex(where: { Element in
                                Element.id == color.id
                            }) {
                                withAnimation(.autoAnimation) {
                                    _ = Colors.remove(at: int)
                                }
                            }
                        } label: {
                            Label("删除", systemImage: "trash")
                        }
                    }
                }
                Button {
                    showColorPicker = true
                } label: {
                    RoundedRectangle(cornerRadius: 8, style: .continuous)
                        .stroke(lineWidth: 8)
                        .overlay {
                            Image(systemName: "plus")
                                .font(.custom(size: .body))
                                .bold()
                        }
                        .foregroundStyle(.white)
                        .clipShape(RoundedRectangle(cornerRadius: 8))
                }
                .popover(isPresented: $showColorPicker) {
                    ColorPannicADD { CGColor in
                        AddColor = UIColor(cgColor: CGColor)
                    }
                    .overlay(alignment: .topTrailing) {
                        Button {
                            withAnimation(.autoAnimation) {
                                showColorPicker = false
                                if AddColor != .clear {
                                    withAnimation(.autoAnimation) {
                                        Colors.append(IdentifiableColor(color: CodableColor(AddColor)))
                                    }
                                    AddColor = .clear
                                }
                            }
                        } label: {
                            Image(systemName: AddColor != .clear ? "plus" : "xmark")
                                .EditViewLabelStyle()
                        }
                        .EditShadow()
                        .padding(.all, 8)
                    }
                }
            } header: {
                Text("基本")
                   .font(.custom(size: .footnote))
                    .foregroundStyle(.gray)
                    .padding(.all, 4)
                    .frame(maxWidth: .infinity, alignment: .leading)
            }
        }
        .padding(.horizontal, 8)
        .padding(.vertical, 15)
        .compositingGroup()
        .shadow(size: 4)
        .drawingGroup()
    }
    
    
    @ViewBuilder
    func opSet() -> some View {
        HStack {
            Text("不透明度：")
               .font(.custom(size: .footnote))
                .bold()
                .foregroundStyle(.gray)
            
            ValueSlider(value: Binding(get: {
                return DefColor.cgColor.alpha
            }, set: { Value in
                let c = DefColor.rgba
                DefColor = UIColor(red: c.red, green: c.green, blue: c.blue, alpha: Value)
            }), in: 0...1)
                .valueSliderStyle(
                    HorizontalValueSliderStyle(
                        track: HorizontalTrack(view: EmptyView()),
                        thumb: Circle()
                            .foregroundStyle(Color("systemBackColor"))
                            .EditShadow()
                            .overlay {
                                Circle()
                                    .foregroundStyle(Color(DefColor))
                                    .EditShadow()
                                    .opacity(DefColor.cgColor.alpha)
                                    .padding(.all, 2.5)
                            },
                        thumbSize: CGSize(width: 30, height: 30)
                    )
                )
                .padding(.all, 3)
                .background(LinearGradient(colors: [Color.white, Color(DefColor.withAlphaComponent(1))], startPoint: .leading, endPoint: .trailing))
                .frame(height: 36)
                .clipShape(Capsule(style: .continuous))
                .EditShadow()
            
            TextField("100", text: Binding(get: {
                return String(Int(DefColor.cgColor.alpha * 100))
            }, set: { Value in
                if let i = Int(Value) {
                    let c = DefColor.rgba
                    DefColor = UIColor(red: c.red, green: c.green, blue: c.blue, alpha: CGFloat(i) / 100)
                }
            }))
            .font(.custom(size: .footnote))
            .bold()
            .multilineTextAlignment(.trailing)
            .frame(width: 25)
        }
    }
}


struct ColorPannicADD: UIViewControllerRepresentable {
    typealias UIViewControllerType = UIColorPickerViewController
    
    let colorback:(CGColor) -> Void
    
    func makeUIViewController(context: Context) -> UIColorPickerViewController {
        let picker = UIColorPickerViewController()
        picker.delegate = context.coordinator
        picker.selectedColor = .clear
        
        return picker
    }
    
    func updateUIViewController(_ uiViewController: UIColorPickerViewController, context: Context) { }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator(root: self)
    }
    
    class Coordinator: NSObject,UIColorPickerViewControllerDelegate{
        var root:ColorPannicADD
        
        init(root: ColorPannicADD) {
            self.root = root
        }
        
        
        
        func colorPickerViewController(_ viewController: UIColorPickerViewController, didSelect color: UIColor, continuously: Bool) {
            root.colorback(color.cgColor)
        }
    }
    
}

struct CodableColor: Codable, Equatable, Hashable, Sendable {
    let UIColor:UIColor
    
    init(_ UIColor: UIColor) {
        self.UIColor = UIColor
    }
    
    static func == (lhs: CodableColor, rhs: CodableColor) -> Bool {
        return lhs.UIColor == rhs.UIColor
    }
    func hash(into hasher: inout Hasher) {
        hasher.combine(UIColor)
    }
    
    enum CodingKeys: CodingKey {
        case R, G, B, A
    }
    enum CodingKeys2: CodingKey {
        case data
    }
    init(from decoder: Decoder) throws {
        do {
            let container = try decoder.container(keyedBy: CodingKeys2.self)
            let data = try container.decode(Data.self, forKey: .data)
            let Colorc = try NSKeyedUnarchiver.unarchivedObject(ofClass: SwiftUI.UIColor.self, from: data)
            self.UIColor = Colorc ?? .black
        } catch {
            do {
                let singleContainer = try decoder.singleValueContainer()
                guard let Colorc = try NSKeyedUnarchiver.unarchivedObject(ofClass: SwiftUI.UIColor.self, from: singleContainer.decode(Data.self)) else {
                    throw DecodingError.dataCorruptedError(in: singleContainer, debugDescription: "Data is corrupted")
                }
                self.UIColor = Colorc
            } catch {
                let container = try decoder.container(keyedBy: CodingKeys.self)
                let R = try container.decode(Double.self, forKey: .R)
                let G = try container.decode(Double.self, forKey: .G)
                let B = try container.decode(Double.self, forKey: .B)
                let A = try container.decode(Double.self, forKey: .A)
                self.UIColor = SwiftUI.UIColor(red: R, green: G, blue: B, alpha: A)
            }
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys2.self)
        try container.encode(NSKeyedArchiver.archivedData(withRootObject: UIColor, requiringSecureCoding: false), forKey: .data)
        
    }
}
extension UIColor {
    var rgba: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var red: CGFloat = 0
        var green: CGFloat = 0
        var blue: CGFloat = 0
        var alpha: CGFloat = 0
        getRed(&red, green: &green, blue: &blue, alpha: &alpha)

        return (red, green, blue, alpha)
    }
}
typealias FontSize = CGFloat

extension Font {
    static func custom(size: FontSize) -> Font {
        return .custom("SongTi SC", size: size)
    }
}
extension FontSize {
    public static let largeTitle: CGFloat = 34

    /// A font with the title text style.
    public static let title: CGFloat = 28
    
    public static let title2: CGFloat = 22
    
    public static let title3: CGFloat = 20

    /// A font with the headline text style.
    public static let headline: CGFloat = 17

    /// A font with the subheadline text style.
    public static let subheadline: CGFloat = 15

    /// A font with the body text style.
    public static let body: CGFloat = 17

    /// A font with the callout text style.
    public static let callout: CGFloat = 16

    /// A font with the footnote text style.
    public static let footnote: CGFloat = 13

    /// A font with the caption text style.
    public static let caption: CGFloat = 12

    public static let caption2: CGFloat = 11
}

extension View {
    func EditViewLabelStyle(_ padding: Bool = false) -> some View {
        self
            .font(.custom(size: .body))
            .frame(minWidth: 35, minHeight: 35)
            .padding([.leading, .trailing], padding ? 13 : 0)
            .background(.background)
            .clipShape(Capsule(style: .continuous))
            .hoverEffect(.automatic)
    }
    func EditViewViewStyle() -> some View {
        self
            .font(.custom(size: .body))
            .frame(minWidth: 35, minHeight: 35)
            .padding(.all, 7)
            .background(.regularMaterial)
            .clipShape(RoundedRectangle(cornerRadius: 13))
            .hoverEffect(.automatic)
    }
    func EditShadow() -> some View {
        self
            .shadow(size: 0.3)
            .shadow(size: 8, offset: CGPoint(x: 0, y: 3))
    }
}
